package org.vaadin.addon.customfield.demo;

import java.util.Set;

import org.vaadin.addon.customfield.beanfield.BeanFieldWrapper;
import org.vaadin.addon.customfield.beanfield.BeanSetFieldWrapper;
import org.vaadin.addon.customfield.demo.data.Person;
import org.vaadin.addon.customfield.demo.data.Team;

import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanContainer;
import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.TwinColSelect;
import com.vaadin.ui.VerticalLayout;

/**
 * Demonstrate conversions between identifiers in selection fields and beans or
 * collections of beans in the underlying item.
 */
public class BeanFieldExample extends CustomComponent {
    private Form teamForm;
    private Container personContainer;
    private VerticalLayout layout;
    private Button commitButton;

    public BeanFieldExample() {
        layout = new VerticalLayout();
        layout.setMargin(true);

        layout.addComponent(new Label(
                "Conversion between bean identifiers and beans."));

        layout.addComponent(getTeamForm());

        commitButton = new Button("Save");
        commitButton.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                getTeamForm().commit();
                BeanItem<Team> item = (BeanItem<Team>) getTeamForm()
                        .getItemDataSource();
                String message = "";
                Person manager = (Person) item.getItemProperty("manager")
                        .getValue();
                if (null != manager) {
                    message = message + "The team manager is "
                            + manager.getFirstName() + " "
                            + manager.getLastName() + ".<br>";
                }
                for (Person member : (Set<Person>) item.getItemProperty(
                        "members").getValue()) {
                    message = message + "Team member: " + member.getFirstName()
                            + " " + member.getLastName() + "<br>";
                }
                getWindow().showNotification(message);
            }
        });
        layout.addComponent(commitButton);

        setCompositionRoot(layout);
    }

    public Form getTeamForm() {
        if (null == teamForm) {
            teamForm = new Form();
            teamForm.setWidth("350px");

            teamForm.setFormFieldFactory(new DefaultFieldFactory() {
                @Override
                public Field createField(Item item, Object propertyId,
                        Component uiContext) {
                    Field field = null;
                    if ("manager".equals(propertyId)) {
                        // The Team bean has a Person instance, whereas the
                        // value of a ComboBox here is an identifier.
                        ComboBox select = new ComboBox("manager",
                                getPersonContainer());
                        select.setItemCaptionPropertyId("firstName");
                        field = new BeanFieldWrapper<Person>(select,
                                Person.class, getPersonContainer(), "lastName");
                    } else if ("members".equals(propertyId)) {
                        // The Team bean has a Set of Person, whereas the value
                        // of a TwinColSelect here is a set of identifiers.
                        // Therefore, we need to convert between the two sets.
                        TwinColSelect select = new TwinColSelect(null,
                                getPersonContainer());
                        select.setMultiSelect(true);
                        select.setItemCaptionPropertyId("firstName");
                        field = new BeanSetFieldWrapper<Person>(select,
                                Person.class, getPersonContainer(), "lastName");
                        field.setCaption(createCaptionByPropertyId(propertyId));
                    } else {
                        field = super.createField(item, propertyId, uiContext);
                        if (field instanceof TextField) {
                            // show null as an empty string
                            ((TextField) field).setNullRepresentation("");
                        }
                    }
                    return field;
                }
            });

            teamForm.setItemDataSource(new BeanItem<Team>(new Team()));
        }
        return teamForm;
    }

    public Container getPersonContainer() {
        if (null == personContainer) {
            BeanContainer<Integer, Person> container = new BeanContainer<Integer, Person>(
                    Person.class);
            container.setBeanIdProperty("lastName");
            container.addBean(new Person("Aarne", "Alainen", null, null));
            container.addBean(new Person("Matti", "Meikäläinen", null, null));
            container.addBean(new Person("Teppo", "Testaaja", null, null));
            personContainer = container;
        }
        return personContainer;
    }

}
